package com.lemon.core.base.context;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.text.CharSequenceUtil;
import com.alibaba.ttl.TransmittableThreadLocal;
import com.lemon.core.base.constant.SecurityConstants;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 登录用户上下文 Holder
 *
 * @author pan
 * @since 2020-07-16
 */
public class UserContextHolder {

    private UserContextHolder() {
    }

    public static final Long DEFAULT_USER_ID = 0L;

    /**
     * 登录用户信息
     */
    private static final ThreadLocal<Map<String, String>> THREAD_LOCAL = new TransmittableThreadLocal<>();

    public static void putAll(Map<String, String> map) {
        map.forEach(UserContextHolder::set);
    }

    public static void set(String key, Object value) {
        Map<String, String> map = getLocalMap();
        map.put(key, value == null ? CharSequenceUtil.EMPTY : value.toString());
    }

    public static <T> T get(String key, Class<T> type) {
        Map<String, String> map = getLocalMap();
        return Convert.convert(type, map.get(key));
    }

    public static <T> T get(String key, Class<T> type, Object def) {
        Map<String, String> map = getLocalMap();
        return Convert.convert(type, map.getOrDefault(key, String.valueOf(def == null ? CharSequenceUtil.EMPTY : def)));
    }

    public static String get(String key) {
        Map<String, String> map = getLocalMap();
        return map.getOrDefault(key, CharSequenceUtil.EMPTY);
    }

    public static Map<String, String> getLocalMap() {
        Map<String, String> map = THREAD_LOCAL.get();
        if (map == null) {
            map = new ConcurrentHashMap<>(16);
            THREAD_LOCAL.set(map);
        }
        return map;
    }

    public static void setLocalMap(Map<String, String> localMap) {
        THREAD_LOCAL.set(localMap);
    }

    /**
     * 移除THREAD_LOCAL
     */
    public static void clear() {
        THREAD_LOCAL.remove();
    }

    /**
     * 获取用户ID
     *
     * @return
     */
    public static Long getUserId() {
        return get(SecurityConstants.USER_ID_KEY, Long.class, DEFAULT_USER_ID);
    }

    /**
     * 设置用户ID
     *
     * @param userId 用户ID
     */
    public static void setUserId(Long userId) {
        set(SecurityConstants.USER_ID_KEY, userId);
    }

    /**
     * 获取获取用户名
     *
     * @return
     */
    public static String getUsername() {
        return get(SecurityConstants.USER_NAME_KEY, String.class);
    }

    /**
     * 设置用户名
     *
     * @param username 用户名
     */
    public static void setUsername(String username) {
        set(SecurityConstants.USER_NAME_KEY, username);
    }

    /**
     * 获取根角色
     *
     * @return
     */
    public static Boolean isRootRole() {
        return get(SecurityConstants.ROOT_ROLE_KEY, Boolean.class, false);
    }

    /**
     * 设置根角色
     *
     * @param rootRole 是否根角色
     */
    public static void setRootRole(Boolean rootRole) {
        set(SecurityConstants.ROOT_ROLE_KEY, rootRole);
    }

    /**
     * 获取用户角色列表
     *
     * @return 角色列表
     */
    public static List<String> getRoles() {
        return get(SecurityConstants.ROLES_KEY, List.class);
    }

    /**
     * 获取用户角色列表
     *
     * @param roles 角色列表
     */
    public static void setRoles(List<String> roles) {
        set(SecurityConstants.ROLES_KEY, roles);
    }

}
